package com.web.base.wechat.provider;

import com.blue.integration.serve.*;
import com.blue.validation.ValidationUtil;
import com.blue.wechat.invoke.InvokeException;
import com.blue.wechat.invoke.WechatContainer;
import com.blue.wechat.invoke.WechatInvoker;
import com.blue.wechat.invoke.model.media.DownloadMedia;
import com.web.base.log.model.Upload;
import com.web.base.log.service.UploadService;
import com.web.base.valid.IdentityCardValid;
import com.web.base.valid.PlateValid;
import com.web.base.valid.VehicleLicenseValid;
import com.web.base.wechat.exception.WechatException;
import com.web.base.wechat.exception.WechatInvokerException;
import com.web.base.wechat.facade.WechatMediaFacade;
import com.web.base.wechat.message.WechatMediaRequest;
import com.web.base.wechat.message.WechatMediaResponse;
import com.web.core.cache.ConfigCache;
import com.web.core.util.Const;
import org.apache.commons.io.FileUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.function.BiFunction;

@Component
public class WechatMediaProvider implements WechatMediaFacade
{
	private static Logger logger = LoggerFactory.getLogger(WechatMediaProvider.class);
	@Resource
	private UploadService uploadService;
	@Resource
	private ConfigCache configCache;
	@Autowired(required = false)
	private WechatContainer wechatContainer;
	@Autowired(required = false)
	private IdentityCardClient identityCardClient;
	@Autowired(required = false)
	private VehicleLicenseClient vehicleLicenseClient;
	@Autowired(required = false)
	private PlateClient plateClient;
	@Resource
	private StorageClient storageClient;
	
	public WechatMediaProvider()
	{
	}

	@Override
	public WechatMediaResponse parseIdentityCard(WechatMediaRequest request) throws InvokeException, OcrException
	{
		ValidationUtil.valid(request, IdentityCardValid.class);
		return this.proccess(request, (f, r) ->
		{
			IdentityCard card = identityCardClient.ocr(request.getSide(), f);
			r.setIdentityCard(card);
			return r;
		});
	}

	@Override
	public WechatMediaResponse parseVehicleLicense(WechatMediaRequest request) throws InvokeException, OcrException
	{
		ValidationUtil.valid(request, VehicleLicenseValid.class);
		return this.proccess(request, (f, r) ->
		{
			VehicleLicense license = vehicleLicenseClient.ocr(f);
			r.setVehicleLicense(license);
			return r;
		});
	}

	@Override
	public WechatMediaResponse parseLicensePlate(WechatMediaRequest request) throws InvokeException, OcrException
	{
		ValidationUtil.valid(request, PlateValid.class);
		return this.proccess(request, (f, r) ->
		{
			LicensePlate plate = plateClient.ocr(f);
			r.setLicensePlate(plate);
			return r;
		});
	}
	
	private WechatMediaResponse proccess(WechatMediaRequest request, BiFunction<File, WechatMediaResponse, WechatMediaResponse> f)
	{
		String code = request.getWechatCode();
		if (code == null || code.isEmpty())
			code = configCache.getValue(Const.WECHAT_CODE);
		if (code == null || code.isEmpty())
			throw new WechatException("找不到微信号配置：" + Const.WECHAT_CODE);
		
		DownloadMedia message = wechatContainer.invoke(code, WechatInvoker.GET_MEDIA, null, request.getMediaId());
		File file = new File(message.getPath());
		Bucket bucket = request.getBucket() == null ? Bucket.FILE : request.getBucket();
		String key = null;
		try
		{
			key = storageClient.save(bucket, file, null);
		}
		catch (IOException e)
		{
			logger.warn("保存文件失败：{}", message.getPath());
		}
		if (key == null)
			throw new WechatInvokerException("保存文件失败");

		Upload upload = new Upload();
		upload.setUserId(request.getUserId());
		upload.setName(file.getName());
		upload.setKey(key);
		upload.setMimeType(message.getMimeType());
		upload.setSize(message.getSize());
		uploadService.save(upload);
		
		WechatMediaResponse response = new WechatMediaResponse();
		response.setMediaId(request.getMediaId());
		response.setUserId(request.getUserId());
		response.setMediaId(request.getMediaId());
		response.setUploadId(upload.getId());
		response.setKey(key);
		response.setSize(upload.getSize());
		response.setUrl(storageClient.getUrl(bucket, key));
		
		response = f.apply(file, response);

		FileUtils.deleteQuietly(file);
		return response;
	}

	@Override
	public WechatMediaResponse upload(WechatMediaRequest request) throws InvokeException
	{
		ValidationUtil.valid(request, VehicleLicenseValid.class);
		return this.proccess(request, (f, r) ->
		{
			return r;
		});
	}
	
}
